home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d945.lha / EmacsStarter / wbarg / wbarg.c < prev    next >
C/C++ Source or Header  |  1993-12-20  |  9KB  |  380 lines

  1. /*
  2.  *  FILE
  3.  *    wbarg V1.0    by Anders Lindgren
  4.  *
  5.  *  DESCRIPTION
  6.  *    Convert WB arguments into shell dito.
  7.  *
  8.  *    This programs looks for a tooltype of the name COMMAND, to which
  9.  *    if adds the WB arguments, before executing the command as a shell
  10.  *    process.
  11.  *
  12.  *    One area of use is to set the COMMAND tooltype to:
  13.  *      COMMAND=sys:rexxc/rx rexxscript
  14.  *    to run the rexx script "rexxscript" with WB arguments. 
  15.  *
  16.  *  WARNING
  17.  *    This is a HACK, it might stop to work on future OS-releases, if
  18.  *    Commodore would change the path mechanism.
  19.  *
  20.  *    This program should work under 1.3, but it hasn't been tested. If
  21.  *    it is runed under V39 it takes advantage of new features. (under 
  22.  *    V37 AllocDosObject(DOS_CLI, ...) is buggy.)
  23.  *
  24.  *  LICENSE
  25.  *      Copyright (C) 1993  Anders Lindgren
  26.  *
  27.  *    This program is free software; you can redistribute it and/or modify
  28.  *    it under the terms of the GNU General Public License as published by
  29.  *    the Free Software Foundation; either version 2 of the License,or
  30.  *    (at your option) any later version.
  31.  *
  32.  *    This program is distributed in the hope that it will be useful,
  33.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  34.  *    MERCHANTABILITY of FITNESS FOR A PARTICULAR PURPOSE. See the
  35.  *    GNU General Public License for more details.
  36.  *
  37.  *    You should have received a copy of the GNU General Public License
  38.  *    along with this program; if not, write to the Free Software
  39.  *    Foundation, Inc., 675 Mass Ave, Cambridge, Ma 02139, USA.
  40.  *
  41.  *  HOW TO CONTACT ME:
  42.  *    voice:   Scream  Anders Lindgren  LOUD
  43.  *    email:   d91ali@csd.uu.se
  44.  *    mail:    Anders Lindgren
  45.  *             Kantorsg. 2-331
  46.  *             S-754 24 Uppsala
  47.  *    SUGA BBS:+46 (0)8 34 85 23
  48.  *         +46 (0)8 34 32 76  
  49.  *
  50.  *  TODO
  51.  *    Define a STACK tooltype to set the stack size.
  52.  *
  53.  *  HISTORY
  54.  *    09-Sep-93    Wrote the program.
  55.  *    28-Sep-93    Added the add/free_cli functions
  56.  *                V1.0 Released
  57.  */
  58.  
  59. #include <exec/types.h>
  60.  
  61. #include <exec/memory.h>
  62. #include <exec/execbase.h>
  63. #include <dos/dos.h>
  64. #include <dos/dostags.h>
  65. #include <workbench/startup.h>
  66.  
  67. #define __USE_SYSBASE
  68.  
  69. #include <proto/exec.h>
  70. #include <proto/dos.h>
  71. #include <proto/icon.h>
  72.  
  73. #include <stdio.h>
  74. #include <strings.h>
  75.  
  76.  
  77. #define CMDLINE 512        /* Length of the command line */
  78.  
  79.  
  80. /* Forward references */
  81.  
  82. int  get_command(struct WBArg * wbarg, char buffer[], int maxlen);
  83. void name_of_lock(BPTR lock, char buffer[], int maxlen);
  84. void usage(void);
  85. int  add_cli(void);
  86. void free_cli(void);
  87.  
  88.  
  89. /* The version string */
  90. UBYTE *vers="\0$VER: wbarg 1.0 (" __DATE__ ")";
  91.  
  92. /* The (secret?) structure of path */
  93.  
  94. struct path {
  95.     BPTR next;
  96.     BPTR lock;
  97. };
  98.  
  99.  
  100. /* A combined cli-structure and BSTR:s used when KS < 39 */
  101. struct mycli {
  102.     struct CommandLineInterface cli; /* Must be the first entry in the structure! */
  103.     UBYTE set_name[80];
  104.     UBYTE command_name[80];
  105.     UBYTE prompt[80];
  106.     UBYTE command_file[80];
  107. };
  108.  
  109.  
  110. void
  111. main(int argc, char *argv[])
  112. {
  113.     char commandline[CMDLINE];    /* The commandline to issue */
  114.     char args[CMDLINE];
  115.  
  116.     struct WBStartup * argmsg;
  117.     struct WBArg     * wbarg;
  118.  
  119.     BPTR olddir;
  120.     BPTR lock;
  121.  
  122.     int found_cmd = FALSE;    /* Flag: TRUE when a COMMAND tooltype is found */
  123.     int created_cli = FALSE;    /* Flag: TRUE when we created our own cli-structure */
  124.  
  125.     int i;
  126.  
  127.     /* If we haven't got a Cli-structure, create one */
  128.     if (Cli() == NULL) {
  129.     if (add_cli()) {
  130.         created_cli = TRUE;
  131.     }
  132.     else {
  133.         puts("wbarg: Error while creating Cli-structure and path\n");
  134.     }
  135.  
  136.     }
  137.  
  138.  
  139.     if (argc) {
  140.     usage();        /* It's no point in running it from the shell */
  141.     }
  142.     else {
  143.     argmsg = (struct WBStartup *)argv;
  144.     wbarg = argmsg->sm_ArgList;
  145.  
  146.     args[0] = '\0';
  147.  
  148.     for (i=0; i<argmsg->sm_NumArgs; i++) {
  149.  
  150.         olddir = -1;
  151.         if ((wbarg->wa_Lock) && (*wbarg->wa_Name)) {
  152.         olddir = CurrentDir(wbarg->wa_Lock);
  153.         }
  154.  
  155.         /* Get the command to execute */
  156.         if (get_command(wbarg, commandline, CMDLINE)) {
  157.         found_cmd = TRUE;
  158.         }
  159.  
  160.         /* Build all the arguments */
  161.         if ((i>0) && *wbarg->wa_Name) {
  162.         if (lock = Lock(wbarg->wa_Name, ACCESS_READ)) {
  163.             strncat(args, " \"", CMDLINE);
  164.             name_of_lock(lock, args, CMDLINE);
  165.             strncat(args, "\"", CMDLINE);
  166.             UnLock(lock);
  167.         }
  168.         }
  169.  
  170.         if (olddir != -1) {
  171.         CurrentDir(olddir);
  172.         }
  173.  
  174.         wbarg++;    /* Use the next argument to the next loop iteration */
  175.     }
  176.  
  177.     if (found_cmd) {
  178.         strncat(commandline, args, CMDLINE);
  179.         Execute(commandline, NULL, NULL);
  180.     }
  181.     else {
  182.         usage();        /* No COMMAND tooltype found */
  183.     }
  184.     }
  185.     if (created_cli) {
  186.     /* ((struct Process *) FindTask(NULL))->pr_CLI = NULL; */
  187.     free_cli();
  188.     }
  189. }
  190.  
  191.  
  192. /*
  193.  *  FUNCTION
  194.  *    get_command
  195.  *
  196.  *  DESCRIPTION
  197.  *    Find a icon with the COMMAND tooltype set.
  198.  */
  199.  
  200. int
  201. get_command(struct WBArg * wbarg, char buffer[], int maxlen)
  202. {
  203.     struct DiskObject * dobj;
  204.     char ** toolarray;
  205.     char * s = NULL;
  206.  
  207.     if ((*wbarg->wa_Name) && (dobj = GetDiskObject(wbarg->wa_Name))) {
  208.     toolarray = (char **)dobj->do_ToolTypes;
  209.  
  210.     if (s = (char *)FindToolType(toolarray, "COMMAND")) {
  211.         s[maxlen-1] = '\0';    /* Make sure the string is nullterminated */
  212.         strncpy(buffer, s, maxlen-1);
  213.     }
  214.     FreeDiskObject(dobj);
  215.     }
  216.     return(s == NULL ? FALSE : TRUE);
  217. }
  218.  
  219.  
  220. /*
  221.  *  FUNCTION
  222.  *    name_of_lock
  223.  *
  224.  *  DESCRIPTION
  225.  *      Create the filename from the lock supplied.
  226.  *      NOTE: The name is ADDED to the string in the buffer.
  227.  */
  228.  
  229. void
  230. name_of_lock(BPTR lock, char buffer[], int maxlen)
  231. {
  232.     BPTR newlock;
  233.         /* Static to save space on the stack during recursion */
  234.     static __aligned struct FileInfoBlock fib; 
  235.     int root;
  236.  
  237.     if (newlock = ParentDir(lock)) {
  238.     name_of_lock(newlock, buffer, maxlen);
  239.     UnLock(newlock);
  240.     root = FALSE;
  241.     }
  242.     else {
  243.     root = TRUE;
  244.     }
  245.  
  246.     if (Examine(lock, & fib)) {
  247.     strncat(buffer, fib.fib_FileName, maxlen);
  248.     if (fib.fib_DirEntryType > 0) {
  249.         strncat(buffer, root ? ":" : "/", maxlen);
  250.     }
  251.     }
  252. }
  253.     
  254.  
  255. /*
  256.  *  FUNCTION
  257.  *    usage
  258.  *
  259.  *  DESCRIPTION
  260.  *    Write a small information text.
  261.  */
  262.  
  263. void
  264. usage(void)
  265. {
  266.     puts("WBARG  A program which converts workbench");
  267.     puts("       arguments to command line dito.");
  268.     puts("Usage: Create a project icon and set"); 
  269.     puts("       the tooltype named COMMAND to the");
  270.     puts("       command you would like to run");
  271.     puts("Example: COMMAND=sys:rexxc/rx someprogram");
  272. }
  273.  
  274.  
  275. /*
  276.  *  FUNCTION
  277.  *    add_cli
  278.  *
  279.  *  DESCRIPTION
  280.  *    Attaches a CommandLineInterface-structure to the current (WB-started)
  281.  *    process and copies the path from the Workbench task.
  282.  *
  283.  *    Return non-FALSE on success;
  284.  */
  285.  
  286. int
  287. add_cli()
  288. {
  289.     struct CommandLineInterface * cli = NULL;
  290.     struct mycli * mycli;
  291.     struct Process * wb;
  292.     BPTR p;            /* The path structure to copy from */
  293.     struct path * newp;        /* The new path structure */
  294.     BPTR * prev;
  295.  
  296.     /*
  297.      * Under 1.3 AllocDosObject does not exists, under <39 the DOS_CLI option is buggy 
  298.      */
  299.     if (SysBase->LibNode.lib_Version < 39) {
  300.     if (mycli = (struct mycli *)AllocMem(sizeof(struct mycli), MEMF_CLEAR|MEMF_PUBLIC)) {
  301.         cli = & mycli->cli;
  302.         mycli->cli.cli_FailLevel   = 10;
  303.         mycli->cli.cli_Background  = DOSTRUE;
  304.         mycli->cli.cli_SetName     = MKBADDR(& mycli->set_name);
  305.         mycli->cli.cli_CommandName = MKBADDR(& mycli->command_name);
  306.         mycli->cli.cli_Prompt      = MKBADDR(& mycli->prompt);
  307.         mycli->cli.cli_CommandFile = MKBADDR(& mycli->command_file);
  308.     }
  309.     }
  310.     else {
  311.     cli = (struct CommandLineInterface *)AllocDosObjectTags(DOS_CLI, TAG_DONE);
  312.     }
  313.     if (cli) {
  314.     cli->cli_DefaultStack = 4096;
  315.     ((struct Process *) FindTask(NULL))->pr_CLI = MKBADDR(cli);
  316.  
  317.     if (wb = (struct Process *)FindTask("Workbench")) {
  318.         prev = & cli->cli_CommandDir;
  319.     
  320.         p = ((struct CommandLineInterface *)BADDR(wb->pr_CLI))->cli_CommandDir;
  321.         while(p){
  322.         if (newp = AllocMem(sizeof(struct path), MEMF_PUBLIC)) {
  323.             newp->lock = DupLock(((struct path *)BADDR(p))->lock);
  324.         
  325.             * prev = MKBADDR(newp);
  326.             prev = & newp->next;
  327.         }
  328.         else {
  329.             * prev = NULL;
  330.             free_cli();
  331.             return(FALSE);
  332.         }
  333.         p = ((struct path *)BADDR(p))->next;
  334.         }
  335.         * prev = NULL;    /* Terminate the linked list */
  336.     }
  337.         return(TRUE);        /* OK */
  338.     }
  339.     return(FALSE);        /* No cli structure allocated */
  340. }
  341.  
  342.  
  343. /*
  344.  *  FUNCTION
  345.  *    free_cli
  346.  *
  347.  *  DESCRIPTION
  348.  *    Undo the work of add_cli
  349.  */
  350.  
  351. void
  352. free_cli()
  353. {
  354.     struct CommandLineInterface * cli;
  355.     struct path * p;
  356.     struct path * p_next;
  357.  
  358.     if (cli = Cli()) {
  359.     p = (struct path *)BADDR(cli->cli_CommandDir);
  360.     cli->cli_CommandDir = NULL;
  361.  
  362.     while (p) {
  363.         p_next = (struct path *)BADDR(p->next);
  364.         if (p->lock) {
  365.         UnLock(p->lock);
  366.         }
  367.         FreeMem((void *)p, sizeof(struct path));
  368.         p = p_next;
  369.     }
  370.     if (SysBase->LibNode.lib_Version < 39) {
  371.         FreeMem((void *)cli, sizeof(struct mycli));
  372.     }
  373.     else {
  374.         FreeDosObject(DOS_CLI, (void *)cli);
  375.     }
  376.  
  377.     ((struct Process *) FindTask(NULL))->pr_CLI = NULL;
  378.     }
  379. }
  380.